﻿using IdentityModel.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace Lynn.Infastructure.Net.Http
{
    public class IdentityInfo
    {
        /// <summary>
        /// Key
        /// </summary>
        public string AppKey { get; set; }
        /// <summary>
        /// 密钥
        /// </summary>
        public string AppSecret { get; set; }
        /// <summary>
        /// 域
        /// </summary>
        public string Scope { get; set; } = "authorize";
        /// <summary>
        /// 授权时间
        /// </summary>
        public int AuthMinutes { get; set; }
        /// <summary>
        /// 基础地址
        /// </summary>
        public string AuthUrl { get; set; }

        internal string Token { get; set; }
        private DateTime AuthTime { get; set; }
        private bool IsAuthOutTime
        {
            get
            {
                TimeSpan ts = DateTime.Now.Subtract(AuthTime);
                return ts.TotalMinutes > AuthMinutes;
            }
        }
        internal async void ToAuth(HttpClient client)
        {
            if (string.IsNullOrWhiteSpace(AuthUrl))
            {
                return;
            }
            //client.BaseAddress = new Uri(BaseUrl);
            if (!IsAuthOutTime)
            {
                client.SetBearerToken(Token);
                return;
            }
            var disco = await client.GetDiscoveryDocumentAsync(new DiscoveryDocumentRequest
            {
                Address = AuthUrl,
                Policy =
                {
                    RequireHttps = false
                }
            });
            if (disco.IsError)
            {
                throw disco.Exception;
            }
            var tokenResponse = await client.RequestClientCredentialsTokenAsync(new ClientCredentialsTokenRequest
            {
                Address = disco.TokenEndpoint,
                ClientId = AppKey,
                ClientSecret = AppSecret,
                Scope = Scope
            });
            if (tokenResponse.IsError)
            {
                throw tokenResponse.Exception;
            }
            Token = tokenResponse.AccessToken;
            client.SetBearerToken(Token);
            AuthTime = DateTime.Now;
        }
    }
}
